using System.Collections.Generic;
using System.IO;
using System.Xml;
using UnityEngine;

public class XMLManager : MonoBehaviour
{
    private string xmlFilePath;

    /// <summary>
    /// 初始化XML管理器
    /// </summary>
    /// <param name="filePath">XML文件路径</param>
    public void Initialize(string filePath)
    {
        xmlFilePath = Path.Combine(Application.persistentDataPath, filePath);
    }

    /// <summary>
    /// 创建新的XML文件
    /// </summary>
    /// <param name="rootElementName">根元素名称</param>
    /// <returns>是否创建成功</returns>
    public bool CreateNewXML(string rootElementName)
    {
        try
        {
            XmlDocument xmlDoc = new XmlDocument();

            // 创建XML声明
            XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", null);
            xmlDoc.AppendChild(xmlDeclaration);

            // 创建根元素
            XmlElement rootElement = xmlDoc.CreateElement(rootElementName);
            xmlDoc.AppendChild(rootElement);

            SaveXML(xmlDoc);
            return true;
        }
        catch (System.Exception e)
        {
            Debug.LogError($"创建XML文件失败: {e.Message}");
            return false;
        }
    }

    /// <summary>
    /// 加载XML文档
    /// </summary>
    /// <returns>XmlDocument对象</returns>
    public XmlDocument LoadXML()
    {
        if (!File.Exists(xmlFilePath))
        {
            Debug.LogWarning($"XML文件不存在: {xmlFilePath}");
            return null;
        }

        try
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(xmlFilePath);
            return xmlDoc;
        }
        catch (System.Exception e)
        {
            Debug.LogError($"加载XML文件失败: {e.Message}");
            return null;
        }
    }

    /// <summary>
    /// 保存XML文档
    /// </summary>
    /// <param name="xmlDoc">要保存的XmlDocument</param>
    /// <returns>是否保存成功</returns>
    public bool SaveXML(XmlDocument xmlDoc)
    {
        try
        {
            // 确保目录存在
            string directory = Path.GetDirectoryName(xmlFilePath);
            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            xmlDoc.Save(xmlFilePath);
            return true;
        }
        catch (System.Exception e)
        {
            Debug.LogError($"保存XML文件失败: {e.Message}");
            return false;
        }
    }

    /// <summary>
    /// 添加新节点
    /// </summary>
    /// <param name="parentNodePath">父节点路径</param>
    /// <param name="nodeName">节点名称</param>
    /// <param name="attributes">属性字典</param>
    /// <param name="innerText">节点文本内容</param>
    /// <returns>是否添加成功</returns>
    public bool AddNode(string parentNodePath, string nodeName, Dictionary<string, string> attributes = null, string innerText = "")
    {
        XmlDocument xmlDoc = LoadXML();
        if (xmlDoc == null) return false;

        try
        {
            XmlNode parentNode = xmlDoc.SelectSingleNode(parentNodePath);
            if (parentNode == null)
            {
                Debug.LogError($"未找到父节点: {parentNodePath}");
                return false;
            }

            XmlElement newNode = xmlDoc.CreateElement(nodeName);

            // 添加属性
            if (attributes != null)
            {
                foreach (var attribute in attributes)
                {
                    newNode.SetAttribute(attribute.Key, attribute.Value);
                }
            }

            // 设置文本内容
            if (!string.IsNullOrEmpty(innerText))
            {
                newNode.InnerText = innerText;
            }

            parentNode.AppendChild(newNode);
            return SaveXML(xmlDoc);
        }
        catch (System.Exception e)
        {
            Debug.LogError($"添加节点失败: {e.Message}");
            return false;
        }
    }

    /// <summary>
    /// 读取节点文本
    /// </summary>
    /// <param name="nodePath">节点路径</param>
    /// <returns>节点文本内容</returns>
    public string ReadNodeText(string nodePath)
    {
        XmlDocument xmlDoc = LoadXML();
        if (xmlDoc == null) return null;

        XmlNode node = xmlDoc.SelectSingleNode(nodePath);
        return node?.InnerText;
    }

    /// <summary>
    /// 读取节点属性
    /// </summary>
    /// <param name="nodePath">节点路径</param>
    /// <param name="attributeName">属性名称</param>
    /// <returns>属性值</returns>
    public string ReadNodeAttribute(string nodePath, string attributeName)
    {
        XmlDocument xmlDoc = LoadXML();
        if (xmlDoc == null) return null;

        XmlNode node = xmlDoc.SelectSingleNode(nodePath);
        if (node is XmlElement element)
        {
            return element.GetAttribute(attributeName);
        }
        return null;
    }

    /// <summary>
    /// 更新节点文本
    /// </summary>
    /// <param name="nodePath">节点路径</param>
    /// <param name="newText">新的文本内容</param>
    /// <returns>是否更新成功</returns>
    public bool UpdateNodeText(string nodePath, string newText)
    {
        XmlDocument xmlDoc = LoadXML();
        if (xmlDoc == null) return false;

        try
        {
            XmlNode node = xmlDoc.SelectSingleNode(nodePath);
            if (node == null)
            {
                Debug.LogError($"未找到节点: {nodePath}");
                return false;
            }

            node.InnerText = newText;
            return SaveXML(xmlDoc);
        }
        catch (System.Exception e)
        {
            Debug.LogError($"更新节点文本失败: {e.Message}");
            return false;
        }
    }

    /// <summary>
    /// 更新节点属性
    /// </summary>
    /// <param name="nodePath">节点路径</param>
    /// <param name="attributeName">属性名称</param>
    /// <param name="attributeValue">属性值</param>
    /// <returns>是否更新成功</returns>
    public bool UpdateNodeAttribute(string nodePath, string attributeName, string attributeValue)
    {
        XmlDocument xmlDoc = LoadXML();
        if (xmlDoc == null) return false;

        try
        {
            XmlNode node = xmlDoc.SelectSingleNode(nodePath);
            if (node is XmlElement element)
            {
                element.SetAttribute(attributeName, attributeValue);
                return SaveXML(xmlDoc);
            }

            Debug.LogError($"节点不是元素类型或未找到: {nodePath}");
            return false;
        }
        catch (System.Exception e)
        {
            Debug.LogError($"更新节点属性失败: {e.Message}");
            return false;
        }
    }

    /// <summary>
    /// 删除节点
    /// </summary>
    /// <param name="nodePath">节点路径</param>
    /// <returns>是否删除成功</returns>
    public bool DeleteNode(string nodePath)
    {
        XmlDocument xmlDoc = LoadXML();
        if (xmlDoc == null) return false;

        try
        {
            XmlNode node = xmlDoc.SelectSingleNode(nodePath);
            if (node == null)
            {
                Debug.LogError($"未找到节点: {nodePath}");
                return false;
            }

            XmlNode parentNode = node.ParentNode;
            if (parentNode != null)
            {
                parentNode.RemoveChild(node);
                return SaveXML(xmlDoc);
            }

            return false;
        }
        catch (System.Exception e)
        {
            Debug.LogError($"删除节点失败: {e.Message}");
            return false;
        }
    }

    /// <summary>
    /// 查询所有匹配的节点
    /// </summary>
    /// <param name="xpath">XPath查询表达式</param>
    /// <returns>节点列表</returns>
    public XmlNodeList QueryNodes(string xpath)
    {
        XmlDocument xmlDoc = LoadXML();
        if (xmlDoc == null) return null;

        try
        {
            return xmlDoc.SelectNodes(xpath);
        }
        catch (System.Exception e)
        {
            Debug.LogError($"查询节点失败: {e.Message}");
            return null;
        }
    }

    /// <summary>
    /// 检查节点是否存在
    /// </summary>
    /// <param name="nodePath">节点路径</param>
    /// <returns>是否存在</returns>
    public bool NodeExists(string nodePath)
    {
        XmlDocument xmlDoc = LoadXML();
        if (xmlDoc == null) return false;

        XmlNode node = xmlDoc.SelectSingleNode(nodePath);
        return node != null;
    }

    public bool FileExists()
    {
        if (File.Exists(this.xmlFilePath))
            return true;
        return false;
    }
}